package com.well.kernel.util.httpclient;

import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import java.util.List;

/**
 * Copyright &copy; Well All rights reserved.
 * Author:Well
 * Date:2017-06-19
 * Description:http客户端的工具类
 */
public class HttpClientUtil
{
    private static Logger logger=Logger.getLogger(HttpClientUtil.class);

    private static CloseableHttpClient client=null;

    /* 最大连接数 */
    public final static int MAX_TOTAL_CONNECTIONS=1000;
    /* 每个路由最大连接数 */
    public final static int MAX_ROUTE_CONNECTIONS=500;
    /* 连接请求时间 毫秒 */
    public final static int CONNECTION_REQUEST_TIMEOUT=60000;
    /* 连接超时时间 毫秒 */
    public final static int CONNECT_TIMEOUT=10000;
    /* 读取超时时间 毫秒 */
    public final static int SOCKET_TIMEOUT=10000;

    static
    {
        /* 自定义的socket工厂类可以和指定的协议(http、https)联系起来，用来创建自定义的连接管理器 */
        PlainConnectionSocketFactory plainCSF= PlainConnectionSocketFactory.getSocketFactory();
        SSLConnectionSocketFactory sslCSF= SSLConnectionSocketFactory.getSocketFactory();
        Registry<ConnectionSocketFactory> registry = RegistryBuilder
                .<ConnectionSocketFactory> create()
                .register("http", plainCSF)
                .register("https", sslCSF).build();
        /* 初始化连接池管理器 */
        PoolingHttpClientConnectionManager connectionManager=new PoolingHttpClientConnectionManager(registry);
        connectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
        connectionManager.setDefaultMaxPerRoute(MAX_ROUTE_CONNECTIONS);
        /* 请求配置 */
        RequestConfig config= RequestConfig.custom()
                .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
                .setConnectTimeout(CONNECT_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT)
                .setRedirectsEnabled(true).build();

        /* cookie */
        CookieStore cookieStore=new BasicCookieStore();
        /* client构建器 */
        HttpClientBuilder clientBuilder= HttpClients.custom()
                .setConnectionManager(connectionManager)
                .setDefaultCookieStore(cookieStore);
        /* 初始化client */
        client=clientBuilder.setDefaultRequestConfig(config).build();
    }

    private HttpClientUtil(){}

    /**
     * http get 请求
     * @param uri 请求地址
     * @return
     */
    public static String get(String uri)
    {
        String content=null;
        CloseableHttpResponse response=null;
        try
        {
            HttpGet get = new HttpGet(uri);
            response=client.execute(get);
            if(null!=response)
            {
                content= EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        }
        catch (Exception e)
        {
            logger.error(e);
        }
        finally
        {
            HttpClientUtils.closeQuietly(response);
        }
        return content;
    }

    /**
     * post 请求，无参数
     * @param uri
     * @return
     */
    public static String post(String uri)
    {
        return post(uri,null);
    }

    /**
     * post请求，有参数
     * @param uri
     * @param params
     * @return
     */
    public static String post(String uri,List<NameValuePair> params)
    {
        String content=null;
        CloseableHttpResponse response=null;
        try
        {
            HttpPost post=new HttpPost(uri);
            if(null!=params)
            {
                post.setEntity(new UrlEncodedFormEntity(params,"UTF-8"));
            }
            response=client.execute(post);
            if(null!=response)
            {
                content= EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        }
        catch (Exception e)
        {
            logger.error(e);
        }
        finally
        {
            HttpClientUtils.closeQuietly(response);
        }
        return content;
    }

}
